﻿#include "mainwindow.h"

#include "appconfig.h"







MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent)
{

	

	logger->info("程序启动");





	bool ret = loadPara();
	if (ret == false)
	{
        QMessageBox::critical(nullptr, "para", "参数文件不存在");
		qApp->quit();
	}

    m_user_passward =  m_settings_para->value("para/user",1).toString();
    m_admin_passeard =  m_settings_para->value("para/admin",1).toString();
    m_login_dialog = new Login_Dialog(this);
    m_login_dialog->setModal(true);
    connect(m_login_dialog->m_login_button, &QPushButton::clicked, this,&MainWindow::login);


	m_vector_show_image.resize(m_camera_number);
	QTimer* m_qtimer = new QTimer(this);
	connect(m_qtimer, &QTimer::timeout, this, [=]() {
		for (auto obj : m_vector_show_image)
		{
			obj = true;
		}
	});
    m_qtimer->start(200);


    m_load_recipe_dialog.m_dir =  m_type_dir;
    m_load_recipe_dialog.setModal(true);
    connect(m_load_recipe_dialog.m_qpushbutton_load, &QPushButton::clicked, this, &MainWindow::loadRecipe);
	initMainWindow();

	////    //*/存图线程开始
	m_save_image_thread = new SaveImageThread();
    m_save_image_thread->run();

	//检测类初始化
	{
        m_result_data.resize(m_camera_number);



		m_qdialog_detection = new QDialog(this);
		m_qdialog_detection->setModal(true);
		m_tabwidget_detection = new QTabWidget(m_qdialog_detection);
		m_tabwidget_detection->move(0, 0);
		m_tabwidget_detection->setFixedSize(1920, 1000);
		for (int i = 0; i < m_camera_number; i++)
		{
			QtThreadProcess* pQtThreadProcess = new QtThreadProcess();
			pQtThreadProcess->m_camera_index = i;
			QString section = "camera" + QString::number(i) + "/";
			pQtThreadProcess->m_camera_name = m_settings_para->value(section + "m_cameraname", QString::number(i)).toString();
			//            pQtThreadProcess->m_detection_number = m_settings_para->value(section + "m_detection_number", 1).toInt();
			//            pQtThreadProcess->m_image_dir = m_settings_para->value(section + "m_image_dir", "").toString();
			//            pQtThreadProcess->m_image_dir = m_exe_directory + "/images/camera" + QString::number(i);







			connect(pQtThreadProcess, &QtThreadProcess::sendDetectionResult, this, &MainWindow::showResult, Qt::QueuedConnection);
			//            connect(pQtThreadProcess, &QtThreadProcess::sendComResult, this, &MainWindow::comResult, Qt::QueuedConnection);
			//            connect(pQtThreadProcess, &QtThreadProcess::sendCameraFinish, this, &MainWindow::cameraFinish, Qt::QueuedConnection);

			QString qstring_path = m_type_dir + "/" + m_type_name + "/" + "camera" + QString::number(i) + ".ini";
			pQtThreadProcess->m_function = new Function(nullptr, qstring_path, "camera" + QString::number(i));
			connect(pQtThreadProcess->m_function->m_pushbutton_return, &QPushButton::clicked, this, &MainWindow::returnMainFrame);
			m_tabwidget_detection->addTab(pQtThreadProcess->m_function, pQtThreadProcess->m_camera_name);

			pQtThreadProcess->start();
			m_vector_detection_thread.push_back(pQtThreadProcess);
		}
	}

	//相机类初始化
	{
		m_qdialog_camera = new QDialog(this);
		m_qdialog_camera->setModal(true);
		m_tabwidget_camera = new QTabWidget(m_qdialog_camera);
		m_tabwidget_camera->move(0, 0);
		m_tabwidget_camera->setFixedSize(1920, 1000);
		for (int i = 0; i < m_camera_number; i++)
		{
            CameraHKQDialog* p = new CameraHKQDialog(nullptr, m_settings_para, "camera" + QString::number(i));
			connect(p->m_qpushbutton_hide, &QPushButton::clicked, this, &MainWindow::returnMainFrame);
			QString section = "camera" + QString::number(i) + "/";
			p->m_camera_name = m_settings_para->value(section + "m_cameraname", QString::number(i)).toString();


			m_tabwidget_camera->addTab(p, p->m_camera_name);
			if (m_online == 1)
			{
				//在线检测
//				logger->info("camera connect");
				p->m_SN = m_settings_para->value(section + "m_SN", QString::number(i)).toString();
				p->m_type = m_settings_para->value(section + "m_type", QString::number(i)).toString();

				bool result = p->initCamera(p->m_type, p->m_SN, callback, m_vector_detection_thread[i]);
				if (result == false)
				{
					QString StringMessage = QString("相机%1连接失败" + p->m_SN).arg(i);
					QImage image(300, 300, QImage::Format_RGB888);
					image.fill(QColor(Qt::black));
					m_vector_show_qlabel[i]->loadtextimage(image, StringMessage, QColor(Qt::red));
					//                    //QMessageBox::information(nullptr, "相机错误", StringMessage);
				}



			}
			if (m_online == 0)
			{
				//离线检测
				p->m_image_dir = m_exe_directory + "/images/camera" + QString::number(i);
				//                p->m_image_dir = m_settings_para->value(section + "m_image_dir", QString::number(i)).toString();
				QDir dir(p->m_image_dir);
				if (!dir.exists())
				{
					QMessageBox::critical(nullptr, "Title", "离线测试文件夹不存在");
				}
				else
				{
					dir.setFilter(QDir::Files | QDir::NoSymLinks);
					QStringList filters;
					filters << "*.bmp" << "*.jpg" << "*.png";
					dir.setNameFilters(filters);

					QStringList  string_list = dir.entryList();
					foreach(QString  var, string_list) {

						m_vector_detection_thread[i]->m_images_path.push_back(p->m_image_dir + "\\" + var);
					}
				}
				QTimer* m_qtimer_offline = new QTimer(this);
				connect(m_qtimer_offline, &QTimer::timeout, this, [=]() {
					m_vector_detection_thread[i]->m_image_index++;
					if (m_vector_detection_thread[i]->m_images_path.size() > 0)
					{
						Mat image_read_file;
						image_read_file = imread(m_vector_detection_thread[i]->m_images_path[(m_vector_detection_thread[i]->m_image_index) % m_vector_detection_thread[i]->m_images_path.size()].toLocal8Bit().toStdString());
						if (!image_read_file.empty())
						{
//							HObject hobject_iamge = matToHImage(image_read_file);
							m_vector_detection_thread[i]->m_camera_index = i;
                            m_vector_detection_thread[i]->m_qDisplayFrameQueue.push_back(image_read_file);
						}
					}
				});
                m_qtimer_offline->start(1000);//固定频率读取离线测试图像
			}
			m_vector_camera.push_back(p);
		}
	}
	//处理类和相机类相互关联
	for (int i = 0; i < m_camera_number; i++)
	{
        connect(m_vector_detection_thread[i], &QtThreadProcess::sendShowImage, m_vector_camera[i], &CameraHKQDialog::showImage);

	}

	//modbus
	{
		m_unuse_use_modbus = m_settings_para->value("para/m_unuse_use_modbus", 0).toInt();
		m_modbus_ip = m_settings_para->value("para/m_modbus_ip", "192.168.1.88").toString();
		m_modbus_port = m_settings_para->value("para/m_modbus_port", 502).toInt();
		if (m_unuse_use_modbus > 0) {
			m_modbus_tcp = modbus_new_tcp(m_modbus_ip.toStdString().c_str(), m_modbus_port);
			if (m_modbus_tcp == nullptr)
				QMessageBox::information(nullptr, "", "PLC设置参数错误");
			else
				if (modbus_connect(m_modbus_tcp) == -1)
					QMessageBox::information(nullptr, "", "PLC连接失败 ");
		}
		if (m_modbus_tcp != nullptr)
		{
            address_ball_number = m_settings_para->value("plc/address_ball_number", 2000).toInt();
            value_ball_number   = m_settings_para->value("plc/value_ball_number", 8).toInt() ;
            modbus_write_register(m_modbus_tcp, address_ball_number, value_ball_number * m_camera_number);

            address_ball_row = m_settings_para->value("plc/address_ball_row", 2001).toInt();
            value_ball_row   = m_settings_para->value("plc/value_ball_row", 2).toInt();
            modbus_write_register(m_modbus_tcp, address_ball_row, value_ball_row);

            address_gap_number = m_settings_para->value("plc/address_gap_number", 2002).toInt();
            value_gap_number   = m_settings_para->value("plc/value_gap_number", 0).toInt();
            modbus_write_register(m_modbus_tcp, address_gap_number, value_gap_number);

			address_ball_times = m_settings_para->value("plc/address_ball_times", 2003).toInt();
			value_ball_times = m_settings_para->value("plc/value_ball_times", 4).toInt();
			modbus_write_register(m_modbus_tcp, address_ball_times, value_ball_times);

            address_ball_delay = m_settings_para->value("plc/address_ball_delay", 0).toInt();
            value_ball_delay   = m_settings_para->value("plc/value_ball_delay", 0).toFloat();
			modbus_write_register(m_modbus_tcp, address_ball_delay, value_ball_delay);
	

			uint16_t registers[2];
            address_rotate_angle = m_settings_para->value("plc/address_rotate_angle", 0).toInt();
            value_rotate_angle   = m_settings_para->value("plc/value_rotate_angle", 0).toFloat();
			
			float_to_registers(value_rotate_angle, registers);
			modbus_write_registers(m_modbus_tcp, address_rotate_angle, 2, registers);

            address_rotate_speed = m_settings_para->value("plc/address_rotate_speed", 0).toInt();
            value_rotate_speed   = m_settings_para->value("plc/value_rotate_speed", 0).toFloat();
			float_to_registers(value_rotate_speed, registers);
			modbus_write_registers(m_modbus_tcp, address_rotate_speed, 2, registers);

            address_ok_position = m_settings_para->value("plc/address_ok_position", 0).toInt();
            value_ok_position   = m_settings_para->value("plc/value_ok_position", 0).toFloat();
			float_to_registers(value_ok_position, registers);
			modbus_write_registers(m_modbus_tcp, address_ok_position, 2, registers);

            address_ng_position = m_settings_para->value("plc/address_ng_position", 0).toInt();
            value_ng_position   = m_settings_para->value("plc/value_ng_position", 0).toFloat();
			float_to_registers(value_ng_position, registers);
			modbus_write_registers(m_modbus_tcp, address_ng_position, 2, registers);

            address_ok_ng_position = m_settings_para->value("plc/address_ok_ng_position", 0).toInt();
            value_ok_ng_position   = m_settings_para->value("plc/value_ok_ng_position", 0).toFloat();
			float_to_registers(value_ok_ng_position, registers);
			modbus_write_registers(m_modbus_tcp, address_ok_ng_position, 2, registers);

            address_ng_ok_position = m_settings_para->value("plc/address_ng_ok_position", 0).toInt();
            value_ng_ok_position   = m_settings_para->value("plc/value_ng_ok_position", 0).toFloat();
			float_to_registers(value_ng_ok_position, registers);
			modbus_write_registers(m_modbus_tcp, address_ng_ok_position, 2, registers);

			address_remove_ball_speed = m_settings_para->value("plc/address_remove_ball_speed", 0).toInt();
			value_remove_ball_speed = m_settings_para->value("plc/value_remove_ball_speed", 0).toFloat();
			float_to_registers(value_remove_ball_speed, registers);
			modbus_write_registers(m_modbus_tcp, address_remove_ball_speed, 2, registers);

			address_remove_ball_positioan = m_settings_para->value("plc/address_remove_ball_positioan", 0).toInt();
			
			


			
            address_adress_result = m_settings_para->value("plc/address_adress_result", 501).toInt();
            


            address_start_or_stop = m_settings_para->value("plc/address_start_or_stop", 0).toInt();


            address_calibration = m_settings_para->value("plc/address_calibration", 0).toInt();

            address_init =m_settings_para->value("plc/address_init", 0).toInt();

            address_ball_front =m_settings_para->value("plc/address_ball_front", 0).toInt();

            address_ball_back =m_settings_para->value("plc/address_ball_back", 0).toInt();





			m_timer_plc = new QTimer(this);


			connect(m_timer_plc, &QTimer::timeout, this, &MainWindow::timerPLC);
			m_timer_plc->start(100);
		}

	}
    


    




    QTimer* m_qTimer_statistics = new QTimer(this);
    m_qTimer_statistics->start(1000*60*60);
    //m_qTimer_statistics->start(1000*60);
    connect(m_qTimer_statistics, &QTimer::timeout, this, &MainWindow::timer_statistics);
//    connect(m_qTimer_statistics, SIGNAL(timeout()), this, SLOT(timer_statistics()));




    Sleep(1000);

	m_qpushbutton_start->setDisabled(false);
	m_qpushbutton_stop->setDisabled(true);
    for (int i = 0; i < m_camera_number; i++)
    {
        m_vector_camera[i]->m_camera_interface->setTriggerMode(0);
    }
}

MainWindow::~MainWindow()
{
    logger->warn("程序关闭");
    for (int i = 0; i < m_camera_number; i++)
    {
        if (m_online == 1)
            m_vector_camera[i]->m_camera_interface->camera_end();
    }
}

void MainWindow::clickCamera()
{
    if(m_login_privilege <2)
    {
        QMessageBox::warning(nullptr, "", "用户登录权限不够");
        return;
    }
    if (m_vector_detection_thread[0]->m_proess_state == false)
    {
        for (int i = 0; i < m_camera_number; i++)
        {
            m_vector_detection_thread[i]->m_show_camera_dialog = true;
        }
        m_qdialog_camera->show();
    }
    else
    {
        QMessageBox::warning(nullptr, "Title", "停止检测，再设置参数");
    }
}

void MainWindow::clickPara()
{
    if(m_login_privilege <2)
    {
        QMessageBox::warning(nullptr, "", "用户登录权限不够");
        return;
    }
    if(value_start_or_stop>0)
    {
        QMessageBox::warning(nullptr, "", "停止plc检测，再设置参数");
        return;
    }

    if (m_vector_detection_thread[0]->m_proess_state == false)
    {
        m_qdialog_detection->show();
    }
    else
    {
        QMessageBox::warning(nullptr, "", "停止检测，再设置参数");
    }
}


void MainWindow::clickStart()
{
	m_qpushbutton_start->setDisabled(true);


	QString type_path = m_exe_directory + "/binary";

	QFileInfo file_ini(type_path);
	if (!file_ini.isFile())
	{
		QMessageBox::critical(nullptr, "", "系统遭到非法修改，请联系供应商");
		return;
	}

	QFile file(type_path);
	//--以只读的 方式打开
	if (!file.open(QIODevice::ReadWrite))
	{
		//--打开失败
		QMessageBox::warning(nullptr, "", "系统遭到非法修改，请联系供应商");
		return;
	}
	//----构建一个QDataStream 对象
	QDataStream in(&file);
	QDateTime data_last;
	//---从二进制文件内读取数据保存在变量里
	in >> data_last;
	//--关闭文件
	file.close();

	QDateTime dateNow(QDateTime::currentDateTime());

	uint data_last_uint = data_last.toTime_t();

	uint dateNow_uint = dateNow.toTime_t();

	int tRet = dateNow_uint - data_last_uint;
	if (tRet < 0)
	{
		QMessageBox::warning(nullptr, "", "系统遭到非法修改，请联系供应商");
		return;
	}
	else
	{
		QDateTime dateTime(QDateTime::currentDateTime());
		QString type_path = m_exe_directory + "/binary";

		QFile file(type_path);
		//---以 只写的方式打开，并清空原文件内容
		file.open(QIODevice::WriteOnly | QIODevice::Truncate);
		QDataStream  out(&file);
		out << dateTime;
		file.close();
	}
	/*if (value_start_or_stop == 0)
	{*/
		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->stopGrabbing();
			m_vector_camera[i]->m_camera_interface->setFrameCount(m_vector_detection_thread[i]->m_function->m_times);

			m_vector_camera[i]->m_qcombox_trigger_mode->setCurrentIndex(1);
			m_vector_camera[i]->m_camera_interface->setTriggerMode(1);


			m_vector_detection_thread[i]->m_vector_result.clear();

		}


		m_result_data_top.clear();
		m_result_data_top.resize(m_camera_number*value_ball_number);

		m_result_data_bottom.clear();
		m_result_data_bottom.resize(m_camera_number*value_ball_number);

		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->startGrabbing();
			m_vector_detection_thread[i]->m_proess_state = true;
		}
		value_start_or_stop = 1;
		if (m_modbus_tcp != nullptr)
			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 1);
	//}
	/*else
	{

		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->stopGrabbing();
			m_vector_detection_thread[i]->m_proess_state = false;
		}
		value_start_or_stop = 0;
		if (m_modbus_tcp != nullptr)
			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);
		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->setTriggerMode(0);
			m_vector_camera[i]->m_camera_interface->startGrabbing();
		}

	}*/

	m_qpushbutton_stop->setDisabled(false);
}

void MainWindow::clickStop()
{
	m_qpushbutton_stop->setDisabled(true);
	
	
	/*if (value_start_or_stop == 0)
	{
		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->stopGrabbing();
			m_vector_camera[i]->m_camera_interface->setFrameCount(m_vector_detection_thread[i]->m_function->m_times);

			m_vector_camera[i]->m_qcombox_trigger_mode->setCurrentIndex(1);
			m_vector_camera[i]->m_camera_interface->setTriggerMode(1);


			m_vector_detection_thread[i]->m_vector_result.clear();

		}


		m_result_data_top.clear();
		m_result_data_top.resize(m_camera_number*value_ball_number);

		m_result_data_bottom.clear();
		m_result_data_bottom.resize(m_camera_number*value_ball_number);

		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->startGrabbing();
			m_vector_detection_thread[i]->m_proess_state = true;
		}
		value_start_or_stop = 1;
		if (m_modbus_tcp != nullptr)
			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 1);
	}
	else
	{*/

		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->stopGrabbing();
			m_vector_detection_thread[i]->m_proess_state = false;
		}
		value_start_or_stop = 0;
		if (m_modbus_tcp != nullptr)
			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);
		for (int i = 0; i < m_camera_number; i++)
		{
			m_vector_camera[i]->m_camera_interface->setTriggerMode(0);
			m_vector_camera[i]->m_camera_interface->startGrabbing();
		}

	/*}*/

	m_qpushbutton_start->setDisabled(false);
}

//void MainWindow::clickStart_or_stop()
//{
//	m_qpushbutton_start->setDisabled(true);
//	
//   
//
//
//	if (value_start_or_stop == 0)
//	{
//		for (int i = 0; i < m_camera_number; i++)
//		{
//			m_vector_camera[i]->m_camera_interface->stopGrabbing();
//            m_vector_camera[i]->m_camera_interface->setFrameCount(m_vector_detection_thread[i]->m_function->m_times);
//
//			m_vector_camera[i]->m_qcombox_trigger_mode->setCurrentIndex(1);
//			m_vector_camera[i]->m_camera_interface->setTriggerMode(1);
//
//
//            m_vector_detection_thread[i]->m_vector_result.clear();
//
//		}
//		
//
//		m_result_data_top.clear();
//		m_result_data_top.resize(m_camera_number*value_ball_number );
//		
//		m_result_data_bottom.clear();
//		m_result_data_bottom.resize(m_camera_number*value_ball_number);
//
//		for (int i = 0; i < m_camera_number; i++)
//		{
//			m_vector_camera[i]->m_camera_interface->startGrabbing();
//			m_vector_detection_thread[i]->m_proess_state = true;
//		}
//		value_start_or_stop = 1;
//		if (m_modbus_tcp != nullptr)
//			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 1);
//	}
//	else
//	{
//
//		for (int i = 0; i < m_camera_number; i++)
//		{
//			m_vector_camera[i]->m_camera_interface->stopGrabbing();
//			m_vector_detection_thread[i]->m_proess_state = false;
//		}
//		value_start_or_stop = 0;
//		if (m_modbus_tcp != nullptr)
//			modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);
//        for (int i = 0; i < m_camera_number; i++)
//        {
//            m_vector_camera[i]->m_camera_interface->setTriggerMode(0);
//            m_vector_camera[i]->m_camera_interface->startGrabbing();
//        }
//
//	}
//}

void MainWindow::closeEvent(QCloseEvent *event)
{
    //QMessageBox::information(nullptr, "", "不能从这里退出");
    event->ignore();
}

void MainWindow::closeSoftware()
{
	if (value_start_or_stop > 0)
	{
		QMessageBox::warning(nullptr, "", "停止plc检测，再退出");
		return;
	}

    int ok = QMessageBox::warning(this, ("退出!"), ("你确定退出吗？"), QMessageBox::Yes, QMessageBox::No);
    if (ok == QMessageBox::Yes)
    {
        m_settings_para->setValue("para/geometry", saveGeometry());
        m_settings_para->setValue("para/state", saveState());
        m_settings_para->sync();
		delete m_settings_para;
        qApp->quit();
    }
}

void MainWindow::initImageControl()
{
    m_image_widget = new QWidget();
    setCentralWidget(m_image_widget);
    QGridLayout* qgridlayout = new QGridLayout();
    qgridlayout->setSizeConstraint(QLayout::SetMinAndMaxSize);
    qgridlayout->setSpacing(1);
    qgridlayout->setMargin(1);
    m_image_widget->setLayout(qgridlayout);
    int step = (m_camera_number+1)/2;
    for(int i=0;i<m_camera_number;i++)
    {
        ShowQLabel* p = new ShowQLabel(m_image_widget);
       // QPictureBox* p = new QPictureBox(m_image_widget);
        m_vector_show_qlabel.push_back(p);
        qgridlayout->addWidget(p,i/step,i%step,1,1);
    }
}

void MainWindow::initPlcPannel()
{
    m_qdockwidget_plc = new QDockWidget(("PLC界面"), this);
    m_qdockwidget_plc->setObjectName("PLC界面");
    m_qdockwidget_plc->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
    addDockWidget(Qt::RightDockWidgetArea, m_qdockwidget_plc);
    menuBar()->addMenu(("PLC界面"))->addAction(m_qdockwidget_plc->toggleViewAction());

    QWidget* qwidget = new QWidget();
    m_qdockwidget_plc->setWidget(qwidget);

    QVBoxLayout* qvobxlayout = new QVBoxLayout();
    qvobxlayout->setSpacing(30);
    qwidget->setLayout(qvobxlayout);

	m_qpushbutton_start = new QPushButton();
	m_qpushbutton_start->setText("启动");
	qvobxlayout->addWidget(m_qpushbutton_start);

	connect(m_qpushbutton_start, &QPushButton::clicked, this, &MainWindow::clickStart);

	m_qpushbutton_stop = new QPushButton();
	m_qpushbutton_stop->setText("停止");
	qvobxlayout->addWidget(m_qpushbutton_stop);

	connect(m_qpushbutton_stop, &QPushButton::clicked, this, &MainWindow::clickStop);


 //   m_qpushbutton_start_or_stop = new QPushButton();
 //   m_qpushbutton_start_or_stop->setText("启动");
 //   qvobxlayout->addWidget(m_qpushbutton_start_or_stop);

	//connect(m_qpushbutton_start_or_stop, &QPushButton::clicked, this,&MainWindow::clickStart_or_stop);



    /*connect(m_qpushbutton_start_or_stop, &QPushButton::clicked, this, [=](){
        if(value_start_or_stop==0)
        {
            for(int i=0;i<m_camera_number;i++)
            {
                m_vector_camera[i]->m_camera_interface->stopGrabbing();
                m_vector_camera[i]->m_camera_interface->setFrameCount(m_vector_detection_thread[i]->m_function->m_times);
                m_vector_camera[i]->m_qcombox_trigger_mode->setCurrentIndex(1);
                m_vector_camera[i]->m_camera_interface->setTriggerMode(1);
            }

            for(int i=0;i<m_camera_number;i++)
            {
                m_vector_camera[i]->m_camera_interface->startGrabbing();
                m_vector_detection_thread[i]->m_proess_state = true;
            }
            value_start_or_stop=1;
            m_qpushbutton_start_or_stop->setText("停止");
			if (m_modbus_tcp != nullptr)
				modbus_write_bit(m_modbus_tcp, address_start_or_stop, 1);
        }
        else
        {
            for(int i=0;i<m_camera_number;i++)
            {
                m_vector_camera[i]->m_camera_interface->stopGrabbing();
                m_vector_detection_thread[i]->m_proess_state = false;
            }
            value_start_or_stop=0;
            m_qpushbutton_start_or_stop->setText("启动");
			if (m_modbus_tcp != nullptr)
				modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);

        }
    });*/

    QPushButton* p_qpushbutton = new QPushButton();
    p_qpushbutton->setText("校准");
    qvobxlayout->addWidget(p_qpushbutton);
    connect(p_qpushbutton, &QPushButton::pressed, this, [=](){
        if(m_modbus_tcp!=nullptr)
            modbus_write_bit(m_modbus_tcp, address_calibration, 1);
    });
    connect(p_qpushbutton, &QPushButton::released, this, [=](){
        if(m_modbus_tcp!=nullptr)
            modbus_write_bit(m_modbus_tcp, address_calibration, 0);
    });


    p_qpushbutton = new QPushButton();
    p_qpushbutton->setText("初始化");
    qvobxlayout->addWidget(p_qpushbutton);
    connect(p_qpushbutton, &QPushButton::pressed, this, [=](){
        if(m_modbus_tcp!=nullptr)
            modbus_write_bit(m_modbus_tcp, address_init, 1);
    });
    connect(p_qpushbutton, &QPushButton::released, this, [=](){
        if(m_modbus_tcp!=nullptr)
            modbus_write_bit(m_modbus_tcp, address_init, 0);
    });



    p_qpushbutton = new QPushButton();
    p_qpushbutton->setText("剔球前进");
    qvobxlayout->addWidget(p_qpushbutton);
    connect(p_qpushbutton, &QPushButton::pressed, this, [=](){
        if(m_modbus_tcp!=nullptr)
			modbus_write_bit(m_modbus_tcp, address_ball_front, 1);
		logger->info("剔球前进1");
    });
    connect(p_qpushbutton, &QPushButton::released, this, [=](){
        if(m_modbus_tcp!=nullptr)
			modbus_write_bit(m_modbus_tcp, address_ball_front, 0);
		logger->info("剔球前进0");
    });

    p_qpushbutton = new QPushButton();
    p_qpushbutton->setText("剔球后退");
    qvobxlayout->addWidget(p_qpushbutton);
    connect(p_qpushbutton, &QPushButton::pressed, this, [=](){
        if(m_modbus_tcp!=nullptr)
			modbus_write_bit(m_modbus_tcp, address_ball_back, 1);
    });
    connect(p_qpushbutton, &QPushButton::released, this, [=](){
        if(m_modbus_tcp!=nullptr)
			modbus_write_bit(m_modbus_tcp, address_ball_back, 0);
    });

	m_qlabel_remove_ball_positioan = new QLabel();
	m_qlabel_remove_ball_positioan->setFixedSize(200, 20);
	qvobxlayout->addWidget(m_qlabel_remove_ball_positioan);

	m_qlabel_all_number = new QLabel();
	m_qlabel_all_number->setFixedSize(200, 20);
	qvobxlayout->addWidget(m_qlabel_all_number);

	m_qlabel_ok_number = new QLabel();
	m_qlabel_ok_number->setFixedSize(200, 20);
	qvobxlayout->addWidget(m_qlabel_ok_number);

    m_qlabel_ok_ratio = new QLabel();
    m_qlabel_ok_ratio->setFixedSize(200, 20);
    qvobxlayout->addWidget(m_qlabel_ok_ratio);


	m_qlabel_speed = new QLabel();
	m_qlabel_speed->setFixedSize(200, 20);
	qvobxlayout->addWidget(m_qlabel_speed);



    p_qpushbutton = new QPushButton();
    p_qpushbutton->setText("实时存图");
    qvobxlayout->addWidget(p_qpushbutton);
    connect(p_qpushbutton, &QPushButton::pressed, this, [=](){
        for(int i=0;i<m_camera_number;i++)
        {

            m_vector_detection_thread[i]->m_save_realtime = true;
        }
    });

}

void MainWindow::initdockPannel()
{
    m_qdockwidget_pannel = new QDockWidget(("控制面板界面"), this);
    m_qdockwidget_pannel->setObjectName("控制面板界面");
    m_qdockwidget_pannel->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
    addDockWidget(Qt::LeftDockWidgetArea, m_qdockwidget_pannel);
    menuBar()->addMenu(("控制面板"))->addAction(m_qdockwidget_pannel->toggleViewAction());

    QWidget* qwidget = new QWidget();
    m_qdockwidget_pannel->setWidget(qwidget);

    QVBoxLayout* qvobxlayout = new QVBoxLayout();
    qvobxlayout->setSpacing(30);
    qwidget->setLayout(qvobxlayout);

	
	for (int i = 0; i < m_camera_number; i++)
	{
		QLabel* pqlabel = new QLabel();
		pqlabel->setFixedSize(200, 20);
		pqlabel->setText("camera" + QString::number(i+1));
		qvobxlayout->addWidget(pqlabel);

		ShowQLabel* p = new ShowQLabel(this);
		p->setFixedSize(225, 50);
		m_vector_qlabel_ball.push_back(p);
		qvobxlayout->addWidget(p);
	}

    m_qpushbutton_user = new QPushButton();
    m_qpushbutton_user->setText("用户权限");
    qvobxlayout->addWidget(m_qpushbutton_user);
    connect(m_qpushbutton_user, &QPushButton::clicked, this, [=](){
        m_login_dialog->show();
    });



    m_qpushbutton_para = new QPushButton();
    m_qpushbutton_para->setText("检测设置");
    qvobxlayout->addWidget(m_qpushbutton_para);
    connect(m_qpushbutton_para, &QPushButton::clicked, this, &MainWindow::clickPara);

    m_qpushbutton_open_image_dir = new QPushButton();
    m_qpushbutton_open_image_dir->setText("打开图像目录");
    qvobxlayout->addWidget(m_qpushbutton_open_image_dir);
    connect(m_qpushbutton_open_image_dir, &QPushButton::clicked, this, [=](){
        QDesktopServices::openUrl(QUrl(m_settings_para->value("para/m_save_image_dir", "").toString(), QUrl::TolerantMode));
    });

    m_qpushbutton_open_clear = new QPushButton();
    m_qpushbutton_open_clear->setText("清除数据");
    qvobxlayout->addWidget(m_qpushbutton_open_clear);
    connect(m_qpushbutton_open_clear, &QPushButton::clicked, this, [=](){
			m_all_number = 0;
			m_error_number = 0;
			m_empty_number = 0;
			 m_error_number_last = 0;
			 m_all_number_last = 0;
			 m_empty_number_last = 0;
             m_qlabel_all_number->setText("总数" + QString::number(m_all_number- m_empty_number));

             m_qlabel_ok_number->setText("合格数" + QString::number(m_all_number - m_empty_number) );

             m_qlabel_ok_ratio->setText("OK数" + QString::number(0) );

    });



    m_qpushbutton_open_help = new QPushButton();
    m_qpushbutton_open_help->setText("打开帮助文档");
    qvobxlayout->addWidget(m_qpushbutton_open_help);
    connect(m_qpushbutton_open_help, &QPushButton::clicked, this, [=](){
        QDesktopServices::openUrl(QUrl::fromLocalFile(m_para_dir + "/help.pdf"));
    });

    m_qpushbutton_open_type_dir = new QPushButton();
    m_qpushbutton_open_type_dir->setText("切换型号");
    qvobxlayout->addWidget(m_qpushbutton_open_type_dir);
    connect(m_qpushbutton_open_type_dir, &QPushButton::clicked, this, [=](){

        m_load_recipe_dialog.updateQListView();
        m_load_recipe_dialog.show();
    });

    m_qpushbutton_exit = new QPushButton();
    m_qpushbutton_exit->setText("退出软件");
    qvobxlayout->addWidget(m_qpushbutton_exit);
    connect(m_qpushbutton_exit, &QPushButton::clicked, this, &MainWindow::closeSoftware);

//    qvobxlayout->addStretch();
}

void MainWindow::initMainWindow()
{
    setWindowTitle("钢球机 型号" + m_type_name);
    setWindowIcon(QIcon(QCoreApplication::applicationDirPath() + "/picture/logo.svg"));

    initdockPannel();
    initPlcPannel();
    initImageControl();

    restoreGeometry(m_settings_para->value("para/geometry").toByteArray());
    restoreState(m_settings_para->value("para/state").toByteArray());
}

bool MainWindow::loadPara()
{
    m_exe_directory = QCoreApplication::applicationDirPath();
    m_para_dir = m_exe_directory + "/para";
    QString path;
    path=   m_para_dir + "/para.ini";
    //创建配置文件操作对象
    m_settings_para = new QSettings(path, QSettings::IniFormat);
    m_settings_para->setIniCodec("UTF-8");
    m_save_data_dir=m_settings_para->value("para/m_save_data_dir","").toString();
    m_type_dir =  m_settings_para->value("para/m_type_dir","").toString();
    m_type_dir =  m_exe_directory + "/" + m_type_dir;
    m_type_name =  m_settings_para->value("para/m_type_name","").toString();
    m_user_passward =  m_settings_para->value("para/m_user_passward","").toString();
    m_admin_passeard =  m_settings_para->value("para/m_admin_passeard","").toString();
    m_camera_number=m_settings_para->value("para/m_camera_number",1).toInt();
    m_online=m_settings_para->value("para/m_online",-1).toInt();
    m_save_image_dir = m_settings_para->value("para/m_save_image_dir", "").toString();
    m_io_ip = m_settings_para->value("para/m_io_ip","").toString();
    return true;
}

void MainWindow::returnMainFrame()
{
    for (int i = 0; i < m_camera_number; i++)
    {
        m_vector_detection_thread[i]->m_show_camera_dialog = false;
    }
    m_qdialog_camera->hide();
    m_qdialog_detection->hide();
}

void MainWindow::saveImage(VectorOutputResult result)
{
    if(result.m_proess_state==false)
    {
        if(result.m_save_realtime>0)
        {

            QString DirName = m_save_image_dir + "/" + result.m_camera_name + "/realtime/";
            QDir dir;
            if (!dir.exists(DirName))
            {
                dir.mkpath(DirName);
            }
            QString path = DirName + QDateTime::currentDateTime().toString("yyyyMMdd_HH_mm_ss_zzz") + ".png";
            m_save_image_thread->addImage(path.toLocal8Bit().toStdString(), result.m_image);
        }
        return;
    }


//    logger->info("save image" + to_string(result.m_camera_index));
    if (result.m_save_right && result.m_detectin_result == true) {
        QString DirName = m_save_image_dir + "/" + result.m_camera_name + "/OK/";
        QDir dir;
        if (!dir.exists(DirName))
        {
            dir.mkpath(DirName);
        }
        QString path = DirName + QDateTime::currentDateTime().toString("yyyyMMdd_HH_mm_ss_zzz  ") + QString::number(result.m_detection_index) + ".png";
        m_save_image_thread->addImage(path.toLocal8Bit().toStdString(), result.m_image);

    }
    if (result.m_save_wrong && result.m_detectin_result == false) {
        QString DirName = m_save_image_dir + "/" + result.m_camera_name + "/NG/";
        QDir dir;
        if (!dir.exists(DirName))
        {
            dir.mkpath(DirName);
        }
        QString path = DirName + QDateTime::currentDateTime().toString("yyyyMMdd_HH_mm_ss_zzz  ") + QString::number(result.m_detection_index)+ ".png";

        m_save_image_thread->addImage(path.toLocal8Bit().toStdString(), result.m_image);
    }

}

void MainWindow::showResult(VectorOutputResult result)
{
    saveImage(result);

    int64 t1 =  cv::getTickCount();

    //数据统计
    if (result.m_vector_result.size()>0)
    {
//            m_result_data[result.m_camera_index].push_back(result.m_vector_result[0]);

            m_result_data[result.m_camera_index].assign(result.m_vector_orign_result.begin(),result.m_vector_orign_result.end());
//            logger->info( "camera:" + std::to_string(result.m_camera_index)+"data end");
            Mat mat_show = result.m_image;

            cv::resize(mat_show, mat_show, Size(m_vector_show_qlabel[result.m_camera_index]->width() , m_vector_show_qlabel[result.m_camera_index]->height()));


            QImage qiamge = matToQImage(mat_show);



            int ok_ratio = 0;
            if (result.m_all_number!=0)
            {
                ok_ratio = (result.m_all_number - result.m_error_number) * 100 / result.m_all_number ;
            }

             QString message_show  =  result.m_camera_name + QString("检测时间%1ms 缺陷数量%2 总数%3 ").arg(result.m_time_use).arg(result.m_error_number).arg(result.m_all_number);
            message_show  +=  result.m_messgae;

            if(result.m_proess_state==false)
            {
                message_show = result.m_camera_name + QString(":序号%1 ").arg(result.m_detection_index);

            }
            if (!qiamge.isNull())
            {
                if(result.m_detectin_result)
                    m_vector_show_qlabel[result.m_camera_index]->loadtextimage(qiamge,message_show  ,QColor(0,255,0));
                else
                    m_vector_show_qlabel[result.m_camera_index]->loadtextimage(qiamge,message_show  ,QColor(255,0,0));
            }
            int64 t2 =  cv::getTickCount();

            double m_time_use = (t2-t1)*1000/getTickFrequency();

			Mat image_out;
			createShowImage(value_ball_number, value_ball_row, result.m_vector_orign_result, image_out);
			QImage Qtempimage = matToQImage(image_out);
			m_vector_qlabel_ball[result.m_camera_index]->loadtextimage(Qtempimage, "", QColor(0, 255, 0));

			///////////////////////////////////////////////////////////////
            if(result.m_camera_index==0)
            {
                int empty_ball = 0;
                for (uint j = 0; j < result.m_vector_orign_result.size(); j++)
                {
                    if (result.m_vector_orign_result[j] == 0)
                    {
                        empty_ball++;
                    }
                }
                if (empty_ball == result.m_vector_orign_result.size())
                {
					m_empty_times++;

                }
                else
                {
					m_empty_times =0;
                }
                if (m_empty_times == 500)
                {
                    logger->info("m_empty_times:" + to_string(m_empty_times));
					m_empty_times = 0;
                    clickStop();
                    if (m_modbus_tcp != nullptr)
                    {
                        modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);
                        modbus_write_bit(m_modbus_tcp, address_empty, 1);
                    }
                    QMessageBox::information(nullptr, "", "连续空料");
                    if (m_modbus_tcp != nullptr)
                    {
                        modbus_write_bit(m_modbus_tcp, address_empty, 0);
                        modbus_write_bit(m_modbus_tcp, address_init, 1);
                        QThread::msleep(200);
                        modbus_write_bit(m_modbus_tcp, address_init, 0);
                    }
                }

			}
			///////////////////////////////////////////////////////////
			/// //判断双球错误，发出停止信号
			for (uint j = 0; j < result.m_vector_orign_result.size(); j++)
			{
				if (result.m_vector_orign_result[j] == -2)
				{
					clickStop();
					if (m_modbus_tcp != nullptr)
					{
						modbus_write_bit(m_modbus_tcp, address_start_or_stop, 0);
						modbus_write_bit(m_modbus_tcp, address_empty, 1);
					}
                    QMessageBox::information(nullptr, "", "钢球异常");
					if (m_modbus_tcp != nullptr)
					{
						modbus_write_bit(m_modbus_tcp, address_empty, 0);
						modbus_write_bit(m_modbus_tcp, address_init, 1);
						QThread::msleep(200);
						modbus_write_bit(m_modbus_tcp, address_init, 0);
					}
					break;
				}
			}
			///////////////////////////////////////////////////////////
	}
	int number = 0;
	for (int i = 0; i < m_camera_number; i++)
	{
		if (m_result_data[i].size() > 0)
		{
			number++;

		}
	}
	if (number == m_camera_number)
	{
		for (int i = 0; i < m_camera_number; i++)
		{
			for (int j = 0; j < value_ball_number; j++)
			{
				int addr_top = i * value_ball_number + j;

				if (m_result_data_top[addr_top].size() > m_camera_number*value_ball_number)
				{
					m_result_data_top[addr_top].erase(m_result_data_top[addr_top].begin());
				}
				m_result_data_top[addr_top].push_back(m_result_data[i][j]);

				if (m_result_data_bottom[addr_top].size() > m_camera_number*value_ball_number)
				{
					m_result_data_bottom[addr_top].erase(m_result_data_bottom[addr_top].begin());
				}
				m_result_data_bottom[addr_top].push_back(m_result_data[i][j + value_ball_number]);

			}
			m_result_data[i].clear();
		}

		bool value_top = false;
		if (m_result_data_top[m_result_data_top.size() - 1].size() >= m_camera_number * value_ball_number)
		{

			int value_tem = 0;
			string string_msg;
			for (int m_result_data_index = 0; m_result_data_index < m_camera_number * value_ball_number; m_result_data_index++)
			{
				value_tem = value_tem + m_result_data_top[m_result_data_top.size() - 1][m_result_data_index];
				string_msg = string_msg + " " + to_string(m_result_data_top[m_result_data_top.size() - 1][m_result_data_index]);
			}
			logger->info("top result:" + string_msg);
			if (0 == value_tem)
			{
				m_empty_number++;
			}
			if (value_tem == m_camera_number * value_ball_number)
			{
				value_top = true;
			}
			else
			{
				value_top = false;
			}
			/*if (m_modbus_tcp != nullptr)
			{
				logger->info("plc:" + to_string(address_adress_result_top) + " result:" + to_string(value));
				modbus_write_register(m_modbus_tcp, address_adress_result_top, value);
			}*/
		}
		else
		{
			logger->info("上面检测次数小于规定,发送错误");
            /*if (m_modbus_tcp != nullptr)
				modbus_write_register(m_modbus_tcp, address_adress_result, 0);
            return;*/
		}
		bool value_bottom = 0;
		if (m_result_data_bottom[m_result_data_bottom.size() - 1].size() >= m_camera_number * value_ball_number)
		{
			int value_tem = 0;
			string string_msg;
			for (int m_result_data_index = 0; m_result_data_index < m_camera_number * value_ball_number; m_result_data_index++)
			{
				value_tem = value_tem + m_result_data_bottom[m_result_data_bottom.size() - 1][m_result_data_index];
				string_msg = string_msg + " " + to_string(m_result_data_top[m_result_data_top.size() - 1][m_result_data_index]);
			}
			logger->info("bottom result:" + string_msg);
			if (0==value_tem)
			{
				m_empty_number++;
			}
			if (value_tem == m_camera_number * value_ball_number)
			{
				value_bottom = true;
			}
			else
			{
				value_bottom = false;
			}
			/*if (m_modbus_tcp != nullptr)
			{
				logger->info("plc:" + to_string(address_adress_result_bottom) + " result:" + to_string(value));
				modbus_write_register(m_modbus_tcp, address_adress_result_bottom, value);
			}*/
		}
		else
		{
			logger->info("下面的球检测次数小于规定,发送错误");
			/*if (m_modbus_tcp != nullptr)
				modbus_write_register(m_modbus_tcp, address_adress_result, 0);
			return;*/
		}
		int value = 0;

		if (m_result_data_bottom[m_result_data_bottom.size() - 1].size() >= m_camera_number * value_ball_number)
		{
			if ((false == value_top) && (false == value_bottom))
			{
				value = 0;
				m_error_number = m_error_number + 2;
				m_all_number = m_all_number + 2;
			}
			else if ((true == value_top) && (true == value_bottom))
			{
				value = 1;
				m_error_number = m_error_number + 0;
				m_all_number = m_all_number + 2;
			}

			else if ((true == value_top) && (false == value_bottom))
			{
				value = 2;
				m_error_number = m_error_number + 1;
				m_all_number = m_all_number + 2;
			}
			else if ((false == value_top) && (true == value_bottom))
			{
				value = 3;
				m_error_number = m_error_number + 1;
				m_all_number = m_all_number + 2;
			}

			if (m_modbus_tcp != nullptr)
			{
				logger->info("plc:" + to_string(address_adress_result) + " result:" + to_string(value));
				modbus_write_register(m_modbus_tcp, address_adress_result, value);
			}
		}
		else
		{
			
			if (m_modbus_tcp != nullptr)
				modbus_write_register(m_modbus_tcp, address_adress_result, 0);
		}

		m_result_data_top.pop_back();
		m_result_data_bottom.pop_back();
		vector<uint> vector_uint;
		m_result_data_top.insert(m_result_data_top.begin(), vector_uint);
		m_result_data_bottom.insert(m_result_data_bottom.begin(), vector_uint);

        m_qlabel_all_number->setText("合格数" + QString::number(m_all_number- m_error_number));

        m_qlabel_ok_number->setText("总数" + QString::number(m_all_number - m_empty_number));

        if(m_all_number - m_empty_number>0)
            m_qlabel_ok_ratio->setText("合格率" + QString::number((m_all_number- m_error_number)*100/(m_all_number - m_empty_number))+"%"
                                       );

    }

	
	

    if(m_vector_show_image[result.m_camera_index]==false)
    {
            return;
    }
    else
    {
        m_vector_show_image[result.m_camera_index] =false;
    }

    Mat mat_show = result.m_image;
        
	cv::resize(mat_show, mat_show, Size(m_vector_show_qlabel[result.m_camera_index]->width() , m_vector_show_qlabel[result.m_camera_index]->height()));


    QImage qiamge = matToQImage(mat_show);



	int ok_ratio = 0;
	if (result.m_all_number!=0)
	{
		ok_ratio = (result.m_all_number - result.m_error_number) * 100 / result.m_all_number ;
	}

     QString message_show  =  result.m_camera_name + QString("检测时间%1ms 缺陷数量%2 总数%3").arg(result.m_time_use).arg(result.m_error_number).arg(result.m_all_number);
    message_show  +=  result.m_messgae;

    if(result.m_proess_state==false)
    {
        message_show = result.m_camera_name + QString(":序号%1 缺陷数量%2 总数%4 ").arg(result.m_detection_index).arg(result.m_error_number).arg(result.m_all_number);

    }



    if (!qiamge.isNull())
    {
        if(result.m_detectin_result)
            m_vector_show_qlabel[result.m_camera_index]->loadtextimage(qiamge,message_show  ,QColor(0,255,0));
        else
            m_vector_show_qlabel[result.m_camera_index]->loadtextimage(qiamge,message_show  ,QColor(255,0,0));
    }
    int64 t2 =  cv::getTickCount();

    double m_time_use = (t2-t1)*1000/getTickFrequency();
//    logger->info( "show time:" + std::to_string(m_time_use ));

}

void MainWindow::timerLoadImage()
{
//    //相机离线测试
//    for (int i = 0; i < m_camera_number; i++)
//    {
//        m_vector_detection_thread[i]->m_image_index++;
//        if (m_vector_detection_thread[i]->m_images_path.size() > 0)
//        {
//            Mat image_read_file;
//            image_read_file = imread(m_vector_detection_thread[i]->m_images_path[(m_vector_detection_thread[i]->m_image_index) % m_vector_detection_thread[i]->m_images_path.size()].toLocal8Bit().toStdString());

//            if (!image_read_file.empty())
//            {
//                m_vector_detection_thread[i]->m_camera_index = i;
//                m_vector_detection_thread[i]->m_qDisplayFrameQueue.push_back(image_read_file);
//            }
//        }
//    }
}

void  MainWindow::timerPLC()
{

    uint16_t plc_write_value = 1  ;
    if (m_modbus_tcp != nullptr)
        modbus_write_registers(m_modbus_tcp,1100,1,&plc_write_value);

    uint8_t read_bits[7]={0,0,0,0,0,0,0};
    if(m_modbus_tcp!=nullptr)
        modbus_read_bits(m_modbus_tcp,address_ok_time_out,7,read_bits);


    if(read_bits[0]==1 || read_bits[1]==1 || read_bits[2]==1 || read_bits[3]==1 || read_bits[4]==1 || read_bits[5]==1 || read_bits[6]==1)
    {

        uint8_t read_bits_init[7]={0,0,0,0,0,0};
        modbus_write_bits(m_modbus_tcp, address_ok_time_out,7,read_bits_init);
        logger->info("plc 发送错误");
		clickStop();

        if(read_bits[0]==1)
            QMessageBox::critical(nullptr,"","全OK传感器感应超时");
        if(read_bits[1]==1)
            QMessageBox::critical(nullptr,"","全NG传感器感应超时");
        if(read_bits[2]==1)
            QMessageBox::critical(nullptr,"","内OK外NG传感器感应超时");
        if(read_bits[3]==1)
            QMessageBox::critical(nullptr,"","内NG外OK传感器感应超时");
        if(read_bits[4]==1)
            QMessageBox::critical(nullptr,"","视觉检测超时");
        if(read_bits[5]==1)
            QMessageBox::critical(nullptr,"","剔球电机未初始化");
        if(read_bits[6]==1)
            QMessageBox::critical(nullptr,"","剔球电机初始化超时");
        if (m_modbus_tcp != nullptr)
        {
            modbus_write_bit(m_modbus_tcp, address_init, 1);
            QThread::msleep(200);
            modbus_write_bit(m_modbus_tcp, address_init, 0);
        }
    }





	uint16_t read_value[2];
    if(m_modbus_tcp!=nullptr)
        modbus_read_registers(m_modbus_tcp, address_remove_ball_positioan, 2, read_value);
	//
	float value;
	memcpy(&value, read_value, 4);
	//

	m_qlabel_remove_ball_positioan->setText("踢球当前位置:" + QString::number(value) +"mm");


    uint16_t tab_reg[2] = {0};
    modbus_read_registers(m_modbus_tcp, 2140, 2, tab_reg);
    value = ((uint32_t)tab_reg[1] << 16) | tab_reg[0];
    m_qlabel_speed->setText("实时速度:"+QString::number(value)+"pcs/h");
    // 获取小时差值



}

void MainWindow::login()
{
    if(m_login_dialog->m_user_edit->currentText()== "user")
    {
        if(m_login_dialog->m_passward_edit->text() ==  m_user_passward)
        {
            m_login_privilege =1;
            m_login_dialog->m_state_label->setText("user 已登录");
            m_login_dialog->hide();
        }
    }
    if(m_login_dialog->m_user_edit->currentText()== "admin")
    {
        if(m_login_dialog->m_passward_edit->text() ==  m_admin_passeard)
        {
            m_login_privilege =2;
            m_login_dialog->m_state_label->setText("admin 已登录");
            m_login_dialog->hide();
        }
    }

    if(m_login_dialog->m_user_edit->currentText()== "super")
    {
        if(m_login_dialog->m_passward_edit->text() == "wuxi")
        {
            QDateTime dateTime(QDateTime::currentDateTime());
            QString type_path  = m_exe_directory+"/binary";

            QFile file(type_path);
                //---以 只写的方式打开，并清空原文件内容
            file.open(QIODevice :: WriteOnly | QIODevice :: Truncate);
            QDataStream  out(&file);
            out<<dateTime;
            file.close();

            m_login_privilege = 2;
            m_login_dialog->m_state_label->setText("super 已登录");
            m_login_dialog->hide();
        }
    }
}

void MainWindow::timer_statistics()
{

	namespace fs = std::filesystem;
	m_data_path = "data/" + QDateTime::currentDateTime().toString("yyyyMMdd") + ".csv";
	fs::path path(m_data_path.toLocal8Bit().toStdString());
	if (!fs::exists(path.parent_path())) {
		try {
			fs::create_directories(path.parent_path());
		}
		catch (const std::exception& e) {
			return ;
		}
	}

	// 以追加模式打开文件，同时判断文件是否存在
	bool file_exists = fs::exists(m_data_path.toLocal8Bit().toStdString());
	std::ofstream file(m_data_path.toLocal8Bit().toStdString(), std::ios::app);

	
	// 如果是新文件且需要表头，则先写入表头
	if (!file_exists) {
        file << "统计时间,检测总数,当前小时合格数,当前小时NG数,当前小时空球数,当前小时的检测数,当前小时的合格率" << endl; // 示例表头
	}
							
	long long_all = m_all_number - m_empty_number;
	long long_empty_now = m_empty_number - m_empty_number_last;
	long long_ng_now = (m_error_number - m_error_number_last) - long_empty_now;
	long long_all_now = m_all_number - m_all_number_last - long_empty_now;
	long long_ok_now = long_all_now - long_ng_now;

	
	
	long ratio_now = 0;
	if (long_all_now > 0)
	{
		ratio_now = long_ok_now * 100 / long_all_now;
	}
	else
	{
		ratio_now = 0;
	}
	file << QDateTime::currentDateTime().toString("yyyyMMdd_HH").toStdString()
		<< "," << long_all
		<< "," << long_ok_now
		<< "," << long_ng_now 
		<< "," << long_empty_now 
		<< "," << long_all_now
		<< "," << ratio_now<< endl;

   /* if(m_empty_number - m_empty_number_last>0)
    {
        file <<QDateTime::currentDateTime().toString("yyyyMMdd_HH").toStdString()
        <<","<<m_all_number- m_empty_number
       << "," << (m_all_number - m_all_number_last) - (m_error_number - m_error_number_last)-(m_empty_number- m_empty_number_last)
       << m_error_number -  m_error_number_last << "," 
       << m_empty_number - m_empty_number_last << "," 
       << m_all_number - m_all_number_last - (m_empty_number - m_empty_number_last)
       << (m_all_number - m_all_number_last)*100/ (m_empty_number - m_empty_number_last)
       << "," << endl;

    }
    else
    {
        file <<QDateTime::currentDateTime().toString("yyyyMMdd_HH").toStdString()
            <<","<<m_all_number- m_empty_number
           << "," << (m_all_number - m_all_number_last) - (m_error_number - m_error_number_last)-(m_empty_number- m_empty_number_last)
           << m_error_number -  m_error_number_last << ","
           << m_empty_number - m_empty_number_last << ","
           << m_all_number - m_all_number_last - (m_empty_number - m_empty_number_last)
           << 0
           << "," << endl;
    }*/
	

    file.close();
	m_error_number_last = m_error_number;
	m_all_number_last   = m_all_number;
	m_empty_number_last = m_empty_number;
    return ;

}

void MainWindow::loadRecipe()
{
    if(m_login_privilege <2)
    {
        QMessageBox::warning(nullptr, "", "用户登录权限不够");
        return;
    }

    if (m_vector_detection_thread[0]->m_proess_state == true)
    {
         QMessageBox::warning(nullptr, "Title", "停止检测，再设置参数");
         return;
    }


    QString name = m_load_recipe_dialog.getTypeName();
    if( name == "")
    {
        QMessageBox::information(nullptr,"没有选择" , "没有选择");
        return;
    }
    QMessageBox *msgBox = new QMessageBox(QMessageBox::Question,name,  "加载型号" + name + "需要关闭软件", QMessageBox::Yes | QMessageBox::No);


    msgBox->button(QMessageBox::Yes)->setText("确认");


    msgBox->button(QMessageBox::No)->setText("退出");

    int res = msgBox->exec();

    if(QMessageBox::Yes == res)
    {


        logger->info("切换型号");


        m_settings_para->setValue("para/m_type_name" ,name);
        m_settings_para->sync();

        const QString program = QCoreApplication::applicationFilePath();
        const QStringList arguments = QCoreApplication::arguments();
        const QString directory_now = QDir::currentPath();
        QCoreApplication::exit();

    }

}
